/*********************************************************************************
 *FileName:  fault_diagnosis.c
 *Author:    ChenJiehong
 *Version:   V1.0
 *Date:      2023-11-29
 ****************************************Includes***********************************/
#include "fault_diagnosis.h"

/***************************************Variables***********************************/

/***************************************Functions***********************************/

/**
 * @brief 堵转检测 位置标定用
 * @param u16ActualPosition:当前执行器位置; u16Current: 当前电流
 * @retval e8Result 堵转标准位状态
 */
MotorStall_t MotorStallCheck_Calibration(uint16_t u16ActualPosition, uint16_t u16Current)
{
    MotorStall_t e8Result = ERR_STALL_NOFOUND;
    uint16_t u16DeltaPosition;

    static uint16_t u16ActualPosition_Last;
    static uint16_t g_u16StallCount = 0;

    if (u16ActualPosition >= u16ActualPosition_Last)
    {
        u16DeltaPosition = u16ActualPosition - u16ActualPosition_Last;
    }
    else
    {
        u16DeltaPosition = u16ActualPosition_Last - u16ActualPosition;
    }

    u16ActualPosition_Last = u16ActualPosition;
    if (u16DeltaPosition < 12 && u16Current > 5)
    {
        g_u16StallCount += 1;

        if (g_u16StallCount >= 30U)
        {
            /* Real stall */
            g_u16StallCount = 0;
            e8Result = ERR_STALL_FOUND;
        }
    }
    else
    {
        if (g_u16StallCount > 1)
            g_u16StallCount -= 1;
    }
    return (e8Result);
}

/**
 * @brief 堵转检测 运行过程中堵转用
 * @param None
 * @retval e8Result 堵转标准位状态
 */
MotorStall_t MotorStallCheck(void)
{
    MotorStall_t e8Result = ERR_STALL_NOFOUND;

    Actuator.Motor.u16MotorRunTimer++;

    if (Actuator.Motor.u16MotorRunTimer >= 200) // 运行超时,也认为是堵转
    {
        Actuator.Motor.u16MotorRunTimer = 0;
        MotorDriverStop();

        int32_t i32Error = (int32_t)Actuator.u16TargetPosition - Actuator.u16ActualPosition;
        if (i32Error > POSITION_DEAD_STALL || i32Error < (-POSITION_DEAD_STALL))
        {
            e8Result = ERR_STALL_FOUND;
        }
        else
        {
            /* MISRA C-2012 Rule 15.7 */
        }
    }
    else
    {
        /* MISRA C-2012 Rule 15.7 */
    }
    return (e8Result);
}

/**
 * @brief 过欠压检测
 * @param u16SupplyVoltage: VS电压
 * @retval e8ErrReturn: 过欠压状态标志位
 */
ErrVoltage_t Under_OverVoltageCheck(uint16_t u16SupplyVoltage)
{
    static ErrVoltage_t e8ErrorVoltage = ERR_VOLTAGE_IN_RANGE;
    static ErrVoltage_t e8ErrorVoltage_Last = ERR_VOLTAGE_IN_RANGE;
    static ErrVoltage_t e8ErrReturn = ERR_VOLTAGE_IN_RANGE;
    static uint16_t u16Err_Count = 0;

    if (u16SupplyVoltage <= APPL_UNDER_VOLT_LEVEL) //0-7.5
    {
        e8ErrorVoltage = ERR_VOLTAGE_UNDER;
    }
    else if (u16SupplyVoltage > APPL_UNDER_VOLT_LEVEL && u16SupplyVoltage < APPL_UNDER_VOLT_RECOVER_LEVEL) //7.5-8.6
    {
        if (e8ErrorVoltage != ERR_VOLTAGE_UNDER)
        {
            e8ErrorVoltage = ERR_VOLTAGE_IN_RANGE;
        }
        else
        {
            e8ErrorVoltage = ERR_VOLTAGE_UNDER;
        }
    }
    else if (u16SupplyVoltage > APPL_OVER_VOLT_RECOVER_LEVEL && u16SupplyVoltage < APPL_OVER_VOLT_LEVEL) //16.5-17
    {
        if (e8ErrorVoltage != ERR_VOLTAGE_OVER)
        {
            e8ErrorVoltage = ERR_VOLTAGE_IN_RANGE;
        }
        else
        {
            e8ErrorVoltage = ERR_VOLTAGE_OVER;
        }
    }
    else if (u16SupplyVoltage >= APPL_OVER_VOLT_LEVEL) //>17
    {
        e8ErrorVoltage = ERR_VOLTAGE_OVER;
    }
    else
    {
        e8ErrorVoltage = ERR_VOLTAGE_IN_RANGE;
    }

    if (e8ErrorVoltage == e8ErrorVoltage_Last)
    {
        u16Err_Count++;
        if (u16Err_Count >= 500)
        {
            e8ErrReturn = e8ErrorVoltage;
            u16Err_Count = 0;
        }
        else
        {
            /* MISRA C-2012 Rule 15.7 */
        }
    }
    else
    {
        u16Err_Count = 0;
    }
    e8ErrorVoltage_Last = e8ErrorVoltage;//记录最后的电压检测状态

    return e8ErrReturn;
}

/**
 * @brief 过温检测
 * @param i16Temperature: 温度值(芯片结温)
 * @retval e8ErrReturn: 过温标志位
 */
ErrTemp_t OverTemperatureCheck(int16_t i16Temperature)
{

    static ErrTemp_t e8ErrorTemperature = ERR_TEMP_NO;
    static ErrTemp_t e8ErrorTemperature_Last = ERR_TEMP_NO;
    static ErrTemp_t e8ErrReturn = ERR_TEMP_NO;

    static uint16_t u16Err_Count = 0;

    if (i16Temperature >= OVER_TEMP_ALARM)
    {
        e8ErrorTemperature = ERR_TEMP_ALARM;
    }
    else if (i16Temperature > OVER_TEMP_WARING && i16Temperature < OVER_TEMP_ALARM)
    {
        e8ErrorTemperature = ERR_TEMP_WARNING;
    }
    else if (i16Temperature > (OVER_TEMP_WARING - TEMPERATURE_HYS) && i16Temperature < OVER_TEMP_WARING)
    {
        if (e8ErrorTemperature != ERR_TEMP_WARNING)
        {
            e8ErrorTemperature = ERR_TEMP_NO;
        }
        else
        {
            e8ErrorTemperature = ERR_TEMP_WARNING;
        }
    }
    else
    {
        e8ErrorTemperature = ERR_TEMP_NO;
    }

    if (e8ErrorTemperature == e8ErrorTemperature_Last)
    {
        u16Err_Count++;
        if (u16Err_Count >= 500)
        {
            e8ErrReturn = e8ErrorTemperature;
            u16Err_Count = 0;
        }
        else
        {
            /* MISRA C-2012 Rule 15.7 */
        }
    }
    else
    {
        u16Err_Count = 0;
    }
    e8ErrorTemperature_Last = e8ErrorTemperature;//记录最后的温度检测状态
    return e8ErrReturn;
}

/**
 * @brief 过流处理函数
 * @param None
 * @retval None
 */
void OverCurrent_Handle(void)
{
    /*停止电机输出*/
    MotorDriverStop();
    /*延时启动*/
    Actuator.u16Stop2StartDelay = 500;
    g_u8OverCurrent_Cnt++;

    if (g_u8OverCurrent_Cnt > 3)
    {
        Actuator.Motor.Fault = MOTOR_COIL_SHORT;
    }
    else
    {
        /* 尝试重启*/
        Actuator.Motor.Request = MOTOR_REQUEST_START;
    }
}

/**
 * @brief 开路检测
 * @param u16Current: 电机运行电流
 * @retval e8Result: 电机开路标志位
 */
MotorFault_t MotorOpenLoadCherck(uint16_t u16Current)
{
    static uint16_t u16OpenLoadCount = 0;
    MotorFault_t e8Result = MOTOR_NO_FAULT;

    if (u16Current < 15)
    {
        u16OpenLoadCount++;
        if (u16OpenLoadCount >= 600) // 5ms 1次
        {
            u16OpenLoadCount = 600;
            e8Result = MOTOR_COIL_OPEN;
        }
        else
        {
            /* MISRA C-2012 Rule 15.7 */
        }
    }
    else
    {
        if (u16OpenLoadCount != 0)
        {
            u16OpenLoadCount--;
        }
        else
        {
            /* MISRA C-2012 Rule 15.7 */
        }
    }

    return e8Result;
}

/***************************************END OF FILE*********************************/
